home *** CD-ROM | disk | FTP | other *** search
-
- Listing 4.
-
- /* sltest.c */
-
- #define SLTEST 1
- #include <stdio.h>
- #include <stdlib.h>
- #include <setjmp.h>
- #include "skiplist.h"
-
- /* globals */
-
- int listsize; /* size of our test list */
- int maxlevel = MAXLEVEL;
- int partition;
- int *emptr; /* dynamic array of list elements */
- int nnodes; /* count of nodes allocated */
- long ctotals; /* total number of comparisons */
- int comps; /* temporary counter */
- int mincomps;
- int maxcomps;
- #define COMPMAX 80 /* width of screen */
- int compary[COMPMAX] = { 0 }; /* for graph routine */
- int overflow = 0;
- int levels[MAXLEVEL] = { 0 };
- jmp_buf errbuf; /* short circuit when out of memory */
- NODE *testlist;
- int orderflag; /* non-zero for random insertions */
- #define SL_RAND_MAX 32767
-
- int intcmp(a, b) /* test comparison routine */
- KEYTYPE a, b;
- {
- comps += 1; /* track length of search path */
- if(a < b)
- return(-1);
- else if(a == b)
- return(0);
- else
- return(1);
- }
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- if(argc < 6)
- usage();
- if((listsize = atoi(argv[i])) < 1)
- usage();
- if(listsize > SL_RAND_MAX)
- {
- listsize = SL_RAND_MAX;
- printf("listsize reduced to %d\n", SL_RAND_MAX);
- }
- if((maxlevel = atoi(argv[2])) < 1)
- usage();
- if(maxlevel > MAXLEVEL)
- {
- maxlevel = MAXLEVEL;
- printf("maxlevel reduced to %d\n", MAXLEVEL);
- }
- if((partition = atoi(argv[3])) < 1)
- || (partition >= maxlevel))
- {
- usage();
- }
- slsrand((unsigned) atoi(argv[4]));
- orderflag = atoi(argv[5]);
-
- list_init();
- list_build();
- list_test();
- list_stats();
- exit(EXIT_SUCCESS);
- }
-
- usage() /* describe command line errors */
- {
- printf("\nUsage:\t");
- printf("sltest <size> <maxlevel> <partition> <seed> <flag>\n");
- printf("\t<size> of test list (>= 1)\n");
- printf("\t<maxlevel> max number of pointers per node (>= 1)\n");
- printf("\t<partition> (>= 1 && < maxlevel [= %d])\n", maxlevel);
- printf("\t<seed> for the random number generator\n");
- printf("\t<flag> 0 for in-order insertions, otherwise random");
- exit(EXIT_FAILURE);
- }
-
- list_init()
- {
- if((emptr = (int *) calloc(listsize, sizeof(int)))
- == NULL)
- {
- nomem();
- }
- if((testlist = newlist()) == NIL)
- nomem();
- }
-
- nomem()
- {
- printf("Not enough memory for a list of size %u\n",
- (unsigned)listsize);
- exit(EXIT_FAILURE);
- }
-
- list_build()
- {
- unsigned slrand();
- unsigned i;
-
- if(setjmp(errbuf))
- listsize = nnodes; /* largest possible */
- else if(orderflag == 0)
- {
- for(nnodes = 0, i = 1; i <= listsize; )
- insert(testlist, i++);
- }
- else
- {
- for(nnodes = 0; nnodes < listsize; )
- insert(testlist, slrand());
- }
- }
-
- list_test()
- {
- int i;
-
- ctotals = 0L;
- mincomps = listsize;
- maxcomps = 0;
- for(i = 0, comps = 0; i < listsize; ++i, comps = 0)
- {
- search(testlist, emptr[i]);
- ctotals += (long) comps;
- if(comps < mincomps)
- mincomps = comps;
- else if(comps > maxcomps)
- maxcomps = comps;
- if(comps < COMPMAX)
- compary[comps] += 1;
- else
- overflow += 1; /* won't fit on screen */
- }
- }
-
- /* for computing behavior of balanced trees */
- unsigned treelevels[] = {
- 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
- 11, 12, 13, 14, 15, 16 };
- unsigned powersof2[] = {
- 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
- 4096, 8192, 16384, (SL_RAND_MAX + 1) };
- int depth;
- long accumulator;
-
- list_stats() /* print out statistics */
- {
- int i;
- int scale;
- int temp;
- int cmax;
-
- printf("\nskiplist size = %d", listsize);
- printf("\npointers per level = ");
- for(i = 0; i < maxlevel; i += 1)
- printf("%d ", levels[i]);
- printf("\ncomparisons per search: ");
- printf("mean = %.3f, minimum = %d, maximum = %d\n",
- ((float)ctotals) / ((float)listsize),
- mincomps, maxcomps);
- if(overflow != 0) /* graph won't fit on screen */
- printf("distribution of comparisons overflows buffer\n");
- else
- {
- cmax = 0;
- for(i = mincomps; i <= maxcomps; i += 1)
- {
- if(compary[i] > cmax)
- cmax = compary[i];
- }
- scale = cmax / 10;
- if(scale == 0) /* watch out for cmax < 10!! */
- scale = 1;
- temp = cmax % 10;
- if((temp / scale) > 5)
- scale += 1;
- for(temp = cmax; temp >= 0; temp -= scale)
- {
- if(temp <= scale) /* last pass through */
- if(scale > 1) /* make sure we */
- temp = 1; /* print all */
- for(i = mincomps; i <= maxcomps; i += 1)
- {
- if(compary[i] / temp)
- printf("*");
- else
- printf(" ");
- }
- printf("\n");
- }
- printf("distribution from minimum through maximum:");
- printf(" scale = %d:1\n", scale);
- }
- for(i = 0; (powersof2[i] - 1) < listsize; i += 1)
- ;
- depth = i--; /* maximum for perfectly balanced tree */
- accumulator = ((long) treelevels[i])
- * ((listsize - powersof2[i--]) + 1);
- while(i >= 0)
- {
- accumulator += (long) (treelevels[i]
- * powersof2[i--]);
- }
- printf("for perfect trees: ");
- printf("mean = %.3f, minimum = 1, maximum = %d\n",
- (((float)accumulator) / ((float)listsize)), depth);
- printf("for degenerate trees: ");
- printf("mean = %.3f, minimum = 1, maximum = %d\n",
- ((float) (listsize + 1) / 2), listsize);
- }
-
- /* EOF */
-
-